package com.scaffold.commons.json;

import java.io.IOException;
import java.text.SimpleDateFormat;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
import org.codehaus.jackson.map.ser.CustomSerializerFactory;
import org.codehaus.jackson.map.ser.FilterProvider;
import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter;
import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider;

/**
 * API专用,用于序列化JSON对象
 * @author wangjg
 */
public class ApiObjectMapper extends ObjectMapper {
	private String dateFormat;
	private boolean ignoreNull = true;
	private boolean undefined = false;
	private String[] allowedFields;
	private String[] disallowedFields;
	
	public ApiObjectMapper() {
	}
	
	public void init(){
		this.config2();
	}

	void config1(){
		SerializationConfig cfg = this.getSerializationConfig();
		cfg.setSerializationInclusion(Inclusion.NON_NULL);
		this.configure(SerializationConfig.Feature.WRITE_NULL_MAP_VALUES, false);
		this.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		CustomSerializerFactory sf = new CustomSerializerFactory();
		this.setSerializerFactory(sf);
	}
	
	private void config2(){
		SerializationConfig cfg = this.getSerializationConfig();
		if(ignoreNull){
			this.configure(SerializationConfig.Feature.WRITE_NULL_MAP_VALUES, false);
			this.setSerializationInclusion(Inclusion.NON_NULL);
//			cfg = cfg.withSerializationInclusion(Inclusion.NON_NULL);
//			this.setSerializationConfig(cfg);
		}
		if(dateFormat!=null){
			this.setSerializationConfig(cfg.withDateFormat(new SimpleDateFormat(dateFormat)));
		}
		this.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		
		//---------------
		if(allowedFields!=null && allowedFields.length>0){
			SimpleBeanPropertyFilter filter = null ;
			filter = SimpleBeanPropertyFilter.filterOutAllExcept(allowedFields);
			FilterProvider filterProvider = new SimpleFilterProvider().addFilter("allowedFields", filter);  
			this.setFilters(filterProvider);
		}
		if(disallowedFields!=null && disallowedFields.length>0){
			SimpleBeanPropertyFilter filter = null ;
			filter = SimpleBeanPropertyFilter.serializeAllExcept(disallowedFields);
			FilterProvider filterProvider = new SimpleFilterProvider().addFilter("allowedFields", filter);  
			this.setFilters(filterProvider);
		}
		//---------------
		if(undefined){
			JsonSerializer<Object> nullVs = new JsonSerializer<Object>(){
				public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException,JsonProcessingException {
					jgen.writeRawValue("");
				}
				
			};
			this.getSerializerProvider().setNullValueSerializer(nullVs);
		}
	}

	public void setDateFormat(String format){
		this.dateFormat = format;
	}

	public void setIgnoreNull(boolean ignoreNull) {
		this.ignoreNull = ignoreNull;
	}

	public void setUndefined(boolean undefined) {
		this.undefined = undefined;
	}

	public void setAllowedFields(String[] allowedFields) {
		this.allowedFields = allowedFields;
	}

	public void setDisallowedFields(String[] disallowedFields) {
		this.disallowedFields = disallowedFields;
	}

}